package com.zenithmind.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.task.mapper.TaskAttachmentMapper;
import com.zenithmind.task.pojo.entity.TaskAttachment;
import com.zenithmind.task.pojo.query.TaskAttachmentQuery;
import com.zenithmind.task.pojo.vo.TaskAttachmentVO;
import com.zenithmind.task.service.TaskAttachmentService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 任务附件服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskAttachmentServiceImpl extends ServiceImpl<TaskAttachmentMapper, TaskAttachment> implements TaskAttachmentService {

    @Override
    public PageResult<TaskAttachmentVO> getTaskAttachmentPage(TaskAttachmentQuery query, String userId) {
        Page<TaskAttachment> page = new Page<>(query.getCurrent(), query.getSize());

        LambdaQueryWrapper<TaskAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasText(query.getTaskId()), TaskAttachment::getTaskId, query.getTaskId())
                .in(query.getTaskIds() != null && !query.getTaskIds().isEmpty(), TaskAttachment::getTaskId, query.getTaskIds())
                .like(StringUtils.hasText(query.getFileName()), TaskAttachment::getFileName, query.getFileName())
                .like(StringUtils.hasText(query.getKeyword()), TaskAttachment::getFileName, query.getKeyword())
                .eq(StringUtils.hasText(query.getFileType()), TaskAttachment::getFileType, query.getFileType())
                .in(query.getFileTypes() != null && !query.getFileTypes().isEmpty(), TaskAttachment::getFileType, query.getFileTypes())
                .eq(StringUtils.hasText(query.getUploaderId()), TaskAttachment::getUploaderId, query.getUploaderId())
                .in(query.getUploaderIds() != null && !query.getUploaderIds().isEmpty(), TaskAttachment::getUploaderId, query.getUploaderIds())
                .ge(query.getFileSizeMin() != null, TaskAttachment::getFileSize, query.getFileSizeMin())
                .le(query.getFileSizeMax() != null, TaskAttachment::getFileSize, query.getFileSizeMax())
                .ge(query.getCreateTimeBegin() != null, TaskAttachment::getCreateTime, query.getCreateTimeBegin())
                .le(query.getCreateTimeEnd() != null, TaskAttachment::getCreateTime, query.getCreateTimeEnd())
                .eq(query.getStatus() != null, TaskAttachment::getStatus, query.getStatus())
                .orderByDesc(TaskAttachment::getCreateTime);

        IPage<TaskAttachment> result = page(page, wrapper);

        List<TaskAttachmentVO> voList = result.getRecords().stream()
                .map(attachment -> convertToVO(attachment, userId))
                .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public PageResult<TaskAttachmentVO> getAttachmentPage(String taskId, Integer pageNum, Integer pageSize, String userId) {
        Page<TaskAttachment> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TaskAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasText(taskId), TaskAttachment::getTaskId, taskId)
               .eq(TaskAttachment::getStatus, 1) // 只查询正常状态的附件
               .orderByDesc(TaskAttachment::getCreateTime);
        
        IPage<TaskAttachment> result = page(page, wrapper);
        
        List<TaskAttachmentVO> voList = result.getRecords().stream()
            .map(attachment -> convertToVO(attachment, userId))
            .collect(Collectors.toList());
        
        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public List<TaskAttachmentVO> getTaskAttachments(String taskId, String userId) {
        LambdaQueryWrapper<TaskAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskAttachment::getTaskId, taskId)
               .eq(TaskAttachment::getStatus, 1)
               .orderByDesc(TaskAttachment::getCreateTime);
        
        List<TaskAttachment> attachments = list(wrapper);
        
        return attachments.stream()
            .map(attachment -> convertToVO(attachment, userId))
            .collect(Collectors.toList());
    }

    @Override
    public TaskAttachmentVO getTaskAttachmentById(String id, String userId) {
        TaskAttachment attachment = getById(id);
        if (attachment == null) {
            throw new BusinessException("附件不存在");
        }
        
        return convertToVO(attachment, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTaskAttachment(TaskAttachment attachment, String userId) {
        // 设置上传者信息
        attachment.setUploaderId(userId);
        attachment.setUploaderName(UserContext.getUsername());
        
        // 设置默认值
        if (attachment.getStatus() == null) {
            attachment.setStatus(1); // 正常
        }
        if (attachment.getDownloadCount() == null) {
            attachment.setDownloadCount(0);
        }
        
        // 设置文件信息
        if (StringUtils.hasText(attachment.getFilePath())) {
            String fileName = attachment.getFilePath().substring(attachment.getFilePath().lastIndexOf("/") + 1);
            if (!StringUtils.hasText(attachment.getFileName())) {
                attachment.setFileName(fileName);
            }
            
            // 设置文件类型
            if (!StringUtils.hasText(attachment.getFileType())) {
                String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                attachment.setFileType(fileExtension);
            }
        }
        
        boolean result = save(attachment);
        
        if (result) {
            log.info("用户 {} 上传附件到任务 {}: {}", userId, attachment.getTaskId(), attachment.getFileName());
            // TODO: 更新任务附件数量等
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTaskAttachment(TaskAttachment attachment, String userId) {
        TaskAttachment existingAttachment = getById(attachment.getId());
        if (existingAttachment == null) {
            throw new BusinessException("附件不存在");
        }
        
        // 权限检查：只有上传者可以编辑
        if (!existingAttachment.getUploaderId().equals(userId)) {
            throw new BusinessException("无权限编辑该附件");
        }
        
        boolean result = updateById(attachment);
        
        if (result) {
            log.info("用户 {} 更新附件: {}", userId, attachment.getFileName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteTaskAttachment(String id, String userId) {
        TaskAttachment attachment = getById(id);
        if (attachment == null) {
            throw new BusinessException("附件不存在");
        }
        
        // 权限检查：只有上传者可以删除
        if (!attachment.getUploaderId().equals(userId)) {
            throw new BusinessException("无权限删除该附件");
        }
        
        // 软删除
        attachment.setStatus(0);
        boolean result = updateById(attachment);
        
        if (result) {
            log.info("用户 {} 删除附件: {}", userId, attachment.getFileName());
            // TODO: 删除实际文件、更新任务附件数量等
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteTaskAttachments(List<String> ids, String userId) {
        for (String id : ids) {
            deleteTaskAttachment(id, userId);
        }
        return true;
    }

    @Override
    public List<TaskAttachmentVO> getCommentAttachments(String commentId, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public TaskAttachmentVO getAttachmentById(String id, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public TaskAttachmentVO uploadTaskAttachment(String taskId, MultipartFile file, String description, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public TaskAttachmentVO uploadCommentAttachment(String taskId, String commentId, MultipartFile file, String description, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public List<TaskAttachmentVO> batchUploadTaskAttachments(String taskId, MultipartFile[] files, String description, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public void downloadTaskAttachment(String id, String userId, HttpServletResponse response) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public String getAttachmentPreviewUrl(String id, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public PageResult<TaskAttachmentVO> getUserTaskAttachments(String userId, Integer pageNum, Integer pageSize) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public List<TaskAttachmentVO> searchTaskAttachments(String keyword, String fileType, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public List<TaskAttachmentVO> batchUploadAttachments(String taskId, List<MultipartFile> files, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean updateAttachment(TaskAttachment attachment, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean deleteAttachment(String id, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean batchDeleteAttachments(List<String> ids, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public byte[] downloadAttachment(String id, String userId) {
        TaskAttachment attachment = getById(id);
        if (attachment == null) {
            throw new BusinessException("附件不存在");
        }

        // 增加下载次数
        attachment.setDownloadCount(attachment.getDownloadCount() + 1);
        updateById(attachment);

        log.info("用户 {} 下载附件: {}", userId, attachment.getFileName());
        // TODO: 记录下载日志等
        // TODO: 返回文件字节
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public String getDownloadUrl(String id, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Boolean generateThumbnail(String id) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public PageResult<TaskAttachmentVO> getUserAttachments(String userId, Integer pageNum, Integer pageSize) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Object getAttachmentStatistics(String taskId, String userId) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Integer cleanExpiredAttachments(Integer days) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    // ==================== 辅助方法 ====================

    /**
     * 转换为VO对象
     */
    private TaskAttachmentVO convertToVO(TaskAttachment attachment, String userId) {
        TaskAttachmentVO vo = BeanCopyUtils.copyBean(attachment, TaskAttachmentVO.class);
        
        // 设置权限
        vo.setCanEdit(attachment.getUploaderId().equals(userId));
        vo.setCanDelete(attachment.getUploaderId().equals(userId));
        
        // 设置文件大小文本
        vo.setFileSizeText(formatFileSize(attachment.getFileSize()));
        
        // 设置文件图标
        vo.setFileIcon(getFileIcon(attachment.getFileType()));
        
        return vo;
    }

    /**
     * 格式化文件大小
     */
    private String formatFileSize(Long fileSize) {
        if (fileSize == null || fileSize == 0) {
            return "0 B";
        }
        
        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int unitIndex = 0;
        double size = fileSize.doubleValue();
        
        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }
        
        return String.format("%.1f %s", size, units[unitIndex]);
    }

    /**
     * 获取文件图标
     */
    private String getFileIcon(String fileType) {
        if (fileType == null) {
            return "file";
        }
        
        switch (fileType.toLowerCase()) {
            case "jpg":
            case "jpeg":
            case "png":
            case "gif":
            case "bmp":
                return "image";
            case "pdf":
                return "pdf";
            case "doc":
            case "docx":
                return "word";
            case "xls":
            case "xlsx":
                return "excel";
            case "ppt":
            case "pptx":
                return "powerpoint";
            case "txt":
                return "text";
            case "zip":
            case "rar":
            case "7z":
                return "archive";
            default:
                return "file";
        }
    }
}
